#include "log.h"

#include "../time.h"

namespace sfc::log {

struct Console : io::Stdout {
  static const inline Str HEAD[] = {"[::]", "[--]", "[**]", "[??]", "[!!]", "[XX]"};
  static const inline Str ATTR[] = {"\e[39m", "\e[32m", "\e[36m", "\e[33m", "\e[31m", "\e[41m"};

  static constexpr u32 NIDX = sizeof(HEAD) / sizeof(*HEAD);

  static const inline auto PROC_TIME = time::Instant::now();

  void entry(Level level) {
    const auto level_idx = u32(level);
    if (level_idx >= NIDX) {
      return;
    }

    const auto time = time::Instant::now() - PROC_TIME;

    const auto is_tty = io::Stdout::is_tty();
    if (is_tty) this->write_str(ATTR[level_idx]);
    this->write_str(HEAD[level_idx]);
    if (is_tty) this->write_str("\e[0m");

    if (is_tty) {
      const auto column = io::Stdout::get_column();
      fmt::write(*this, "\e[{}G\e[38;5;240m{7.3f}\e[0m\e[6G", column - 8, time.secs());
    } else {
      fmt::write(*this, "{7.3f} ", time.secs());
    }
  }
};

auto logger() -> Logger& {
  static auto default_backend = Console();
  static auto default_logger = Logger{default_backend};
  return default_logger;
}

}  // namespace sfc::log
